import React, { PureComponent } from 'react'
import { connect, withRouter } from '@umijs/max'
import { Form, Input, message, Modal, Select, Spin, TreeSelect } from 'antd'
import list2tree from 'list2tree'
import { ExclamationCircleFilled } from '@ant-design/icons'
import Tools from '@/utils/Tools'
import { defaultIconFun, HufuTreeTitle, ProTree, searchTreeListByName } from '@/components'
import { TreeIcon } from '../../../../components'
import { getHashParameterByName } from '@/utils/helper'
import styles from './index.less'
import { deleteTask, getDirTree, saveDir, saveTask } from './api'

const Bus = Tools.Bus
const { Item } = Form
const { Option } = Select
const { TextArea } = Input
const isDir = (nodeType) => [0, 1, 2, 3, 4].includes(nodeType)
const getNavTreeDataFunc = list2tree({
  idKey: 'id',
  parentIdKey: 'pid',
  newKey: {
    key: 'id',
    value: 'id',
    title: 'name',
  },
})

/**
 * 数据开发任务类型 ----------------------------nodeType-----------------------------------
 * 0：普通目录
 * 1：工作流程目录
 * 2：数据集成目录
 * 3：数据开发目录
 * 4：数据质量目录
 * 10：资源
 * 11：函数
 * 12：开始节点
 * 13：sql
 * 14：mr
 * 15：impala
 * 16：shell
 * 17：python2
 * 18：python3
 * 19：pyspark
 * 20：离线同步
 * 21：接口采集
 * 22：数据质量
 * */

// @connect(({ scriptDev }) => ({ ...scriptDev }))
class DataDevTree extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      // expandArr: [],
      modifyId: null,
      isShowTask: false,
      navListSpinning: false,
      isShowFiles: false,
      treeOption: [],
      // fItem: null,
      // cItem: null,
      treeDataNew: props.treeList || [],
    }

    this.taskForm = React.createRef()
    this.fileForm = React.createRef()
  }

  componentDidMount() {
    this.refresh()
    Bus.addListener('ShowTaskModal', this.showTaskModal)
    Bus.addListener('RefreshDevTree', this.refresh)
    document.addEventListener('keydown', this.handleKeyDown)
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.treeList != this.props.treeList) {
      this.setState({
        treeDataNew: nextProps.treeList,
      }, () => {
        const queryNodeId = getHashParameterByName('nodeId')
        const queryNodeName = getHashParameterByName('nodeName')
        if (queryNodeId) {
          setTimeout(() => {
            this.props.onSelect([queryNodeId])
            const searchTree = searchTreeListByName(
              queryNodeName,
              this.props?.treeLists,
            )
            this.tree.onExpand(searchTree.fatchIds)
          })
        }
      })
    }
  }

  componentWillUnmount() {
    Bus.removeListener('ShowTaskModal', this.showTaskModal)
    Bus.removeListener('RefreshDevTree', this.refresh)
    document.removeEventListener('keydown', this.handleKeyDown)
  }

  // 获取树状列表
  getTreeList = () => {
    this.setState({ navListSpinning: true })
    this.props.dispatch({
      type: 'scriptDev/GetTrees',
      params: {
        id: 1,
      },
      cb: (res) => {
        this.setState({ navListSpinning: false })
      },
    })
  }

  // 获取目录选项列表
  getDirTreeOption = () => {
    getDirTree({ id: 1 }).then(
      (res) => {
        if (res && res[0]) {
          const { childs } = res[0]
          this.setState({
            treeOption: childs,
          })
        } else {
          this.setState({
            treeOption: [],
          })
        }
      },
      (error) => {
        console.log(error)
      },
    )
  }

  // 打开新建目录弹窗
  showFilesModal = (id) => {
    this.fileForm.current?.resetFields()
    this.setState({
      modifyId: null,
      isShowFiles: true,
    }, () => {
      if (id) {
        this.fileForm.current.setFieldsValue({ pid: id })
      }
    })
  }

  // 编辑打开新建目录弹窗
  editFilesModal = (item) => {
    this.fileForm.current?.resetFields()
    this.setState({
      modifyId: item.id,
      isShowFiles: true,
    }, () => {
      if (item) {
        this.fileForm.current.setFieldsValue({
          pid: item.pid == '1' ? undefined : item.pid,
          name: item.name,
        })
      }
    })
  }

  // 打开新建工作弹窗
  showTaskModal = (item, pid) => {
    this.taskForm.current?.resetFields()
    this.setState({
      modifyId: item ? item.id : null,
      isShowTask: true,
    }, () => {
      if (item) {
        this.taskForm.current.setFieldsValue({
          pid: (item.pid && item.pid != '1') ? item.pid : undefined,
          taskName: item.name,
        })
      } else if (pid) {
        this.taskForm.current.setFieldsValue({ pid })
      }
    })
  }

  // 刷新
  refresh = () => {
    this.getTreeList()
    this.getDirTreeOption()
  }

  // 按键事件处理
  handleKeyDown = (e) => {
    // // 监听delete按钮时间
    // if (e.key == 'Delete') {
    //   const { selectedKeys } = this.props
    //   if (selectedKeys && selectedKeys.length) {
    //     const item = this.getTask(selectedKeys[0])
    //     if (item) {
    //       this.onDelete(item)
    //     }
    //   }
    // }
  }

  // // 根据id找到任务对象
  // getTask = (id) => {
  //   const { treeLists } = this.props
  //   return treeLists.find((item) => id == item.id)
  // }

  renderTreeNodes = (data, themeValue) => {
    const tempArr = []
    const { selectedKeys } = this.props
    data.map((item) => {
      const {
        name, id, nodeType,
      } = item
      const icon = item.nodeType == 0 ? (props) => defaultIconFun(props, selectedKeys, themeValue) :
        <TreeIcon color="blue" iconName="icon-FlinkSQLrenwu" />
      const tempObj = {
        icon,
        key: id,
        nodeType,
        selectable: [0, 1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22].includes(nodeType),
      }
      tempObj.title = (
        <HufuTreeTitle
          title={name}
          key={item.id}
          icon
          operations={[
            isDir(item.nodeType) ? (
              <a
                key={`newDir${item.id}`}
                onClick={() => this.showFilesModal(item.id)}
              >
                新建目录
              </a>
            ) : null,
            isDir(item.nodeType) ? (
              <a
                key={`new${item.id}`}
                onClick={() => this.showTaskModal(null, item.id)}
              >
                新建作业
              </a>
            ) : null,
            <a
              key={`edit${item.id}`}
              onClick={() => (isDir(item.nodeType) ? this.editFilesModal(item) : this.showTaskModal(item))}
            >
              编辑
            </a>,
            <a
              key={`del${item.id}`}
              onClick={() => {
                this.onDelete(item)
              }}
            >
              删除
            </a>,
          ]}
        />
      )
      if (item.children) {
        tempObj.children = this.renderTreeNodes(item.children, themeValue)
      }
      tempArr.push(tempObj)
    })
    return tempArr
  }

  // 删除方法
  onDelete = (item) => {
    Modal.confirm({
      title: '确认要删除这个任务吗？',
      icon: <ExclamationCircleFilled />,
      content: '删除后数据将无法恢复，请谨慎操作',
      okText: '删除',
      cancelText: '取消',
      okButtonProps: {
        danger: true,
      },
      onOk: () => {
        this.setState({ navListSpinning: true })
        deleteTask({ id: item.id }).then(
          (res) => {
            message.success('删除成功')
            if ([1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22].includes(item.nodeType)) {
              this.props.dispatch({
                type: 'scriptDev/deleteTaskId',
                params: {
                  id: item.id,
                },
              })
            }
            this.refresh()
          },
          (error) => {
            this.setState({ navListSpinning: false })
          },
        )
      },
    })
  }

  // onDragEnter= (opt) => {

  //   // if ([0, 3].indexOf(opt.node.props.data.nodeType) > -1) {
  //   //   this.setState({
  //   //     expandArr: opt.expandedKeys,
  //   //   })
  //   // }
  // }

  // onDrop = (opt) => {
  //   if (!opt.dropToGap) {
  //     this.setState(
  //       {
  //         cItem: opt.dragNode.props.data,
  //         fItem: opt.node.props.data,
  //       },
  //       this.catalogChange,
  //     )
  //   } else {
  //     this.setState(
  //       {
  //         cItem: opt,
  //       },
  //       // this.datadevDirSort,
  //     )
  //   }
  // }

  // 拖动
  // catalogChange = () => {
  //   const cItem = this.state.cItem
  //   const fItem = this.state.fItem
  //   const noChange = (isDir(fItem.nodeType)
  //       && [fItem.nodeType, 13, 14, 15, 16, 17, 18, 19].includes(cItem.nodeType))
  //     || (isDir(fItem.nodeType) && fItem.nodeType == cItem.nodeType)
  //     || (isDir(fItem.nodeType) && cItem.nodeType == 20 && fItem.nodeType == 2)
  //     || (isDir(fItem.nodeType) && cItem.nodeType == 21 && fItem.nodeType == 2)
  //     || (isDir(fItem.nodeType) && cItem.nodeType == 3 && fItem.nodeType == 3)
  //   if (noChange) {
  //     devDirChange({
  //       pid: fItem.key,
  //       id: cItem.key,
  //     }).then(
  //       (res) => {
  //         message.success('修改成功')
  //         // 当修改完成后，由于可以跨层级拖动，所以为了保险所有的工作流都要刷新
  //         this.refresh()
  //       },
  //       (error) => {
  //         console.log(error)
  //       },
  //     )
  //   } else {
  //     message.warning('此文件不能移动到此目录下')
  //   }
  // }

  // 新建目录确认
  filesOnOk = () => {
    this.fileForm.current.validateFields().then(values => {
      this.setState({ confirmLoading: true })
      if (this.state.modifyId) {
        values.id = this.state.modifyId
      }
      if (!values.pid) values.pid = 1
      saveDir(values).then(
        (res) => {
          message.success(this.state.modifyId ? '修改目录成功' : '新建目录成功')
          this.setState({
            isShowFiles: false,
            confirmLoading: false,
          }, () => {
            this.refresh()
          })
        },
        (error) => {
          this.setState({ confirmLoading: false })
        },
      )
    })
  }

  // 新建作业确认
  taskOnOk = () => {
    this.taskForm.current.validateFields().then(values => {
      this.setState({ confirmLoading: true })
      const { taskName, pid, remark } = values
      const postObj = {
        nodeName: taskName,
        pid: pid || 1,
        remark,
        nodeType: 13,
      }
      if (this.state.modifyId) {
        postObj.id = this.state.modifyId
      }
      saveTask(postObj).then(
        (res) => {
          message.success(this.state.modifyId ? '编辑作业开发成功' : '新建作业开发成功')
          const { tasks } = JSON.parse(JSON.stringify(this.props))
          const task = tasks.find((value) => value.id == postObj.id)
          if (task) {
            task.name = postObj.nodeName
            // 将修改保存至props
            this.props.dispatch({
              type: 'scriptDev/upFlow',
              params: {
                tasks,
              },
            })
          }
          this.setState({
            isShowTask: false,
            confirmLoading: false,
          }, () => {
            this.refresh()
          })
        },
        (error) => {
          this.setState({ confirmLoading: false })
        },
      )
    })
  }

  render() {
    const { treeOption, treeDataNew } = this.state
    const {
      title, selectedKeys, onSelect, themeValue
    } = this.props
    return (
      <div
        className={`${styles.script_dev}`}
      // style={{ display: this.props.navKey == 0 ? 'block' : 'none' }}
      >
        <Spin spinning={this.state.navListSpinning}>
          <div className={styles.datadev_tree_box}>
            <ProTree
              selectedKeys={selectedKeys}
              showSearch
              // onDragEnter={this.onDragEnter}
              // onDrop={this.onDrop}
              // draggable
              onSelect={onSelect}
              title={title || '目录'}
              operations={[
                <i
                  key="0"
                  className="iconfont icon-shuaxin"
                  onClick={() => {
                    this.refresh()
                  }}
                />,
                <i
                  key="1"
                  className="iconfont icon-xinjianwenjianjia"
                  onClick={() => this.showFilesModal(null)}
                />,
                <i
                  key="2"
                  className="iconfont icon-tianjia"
                  onClick={() => this.showTaskModal(null)}
                />,
              ]}
              renderTreeNodes={(data) => this.renderTreeNodes(data, themeValue)}
              ref={(dev) => (this.tree = dev)}
              treeData={treeDataNew}
              search={(name) => {
                const searchTree = searchTreeListByName(
                  name,
                  this.props.treeLists,
                )
                const treeDataNews = getNavTreeDataFunc(
                  searchTree.result,
                )
                this.setState(
                  {
                    treeDataNew: treeDataNews,
                  },
                  () => {
                    this.tree.onExpand(searchTree.fatchIds)
                  },
                )
              }}
            />
          </div>
        </Spin>
        <Modal
          title={this.state.modifyId ? '修改目录' : '新建目录'}
          visible={this.state.isShowFiles}
          confirmLoading={this.state.confirmLoading}
          cancelText="取消"
          okText="保存"
          onOk={this.filesOnOk}
          onCancel={() => {
            this.setState({
              isShowFiles: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              ref={this.fileForm}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 19 }}
              autoComplete="off"
            >
              <Item
                label="目录名称"
                name="name"
                rules={[
                  { required: true, message: '请输入目录名称' },
                ]}
              >
                <Input placeholder="请输入目录名称" />
              </Item>
              <Item
                label="父级目录"
                name="pid"
              >
                <TreeSelect
                  allowClear
                  showSearch
                  getPopupContainer={(triggerNode) => triggerNode.parentNode}
                  // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                  treeData={treeOption}
                  placeholder="请选择父级目录"
                  treeDefaultExpandAll
                  filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  fieldNames={{
                    label: 'name', value: 'id', children: 'childs',
                  }}
                />
              </Item>
            </Form>
          </div>
        </Modal>
        <Modal
          title={
            this.state.modifyId
              ? '编辑作业开发'
              : '新建作业开发'
          }
          confirmLoading={this.state.confirmLoading}
          visible={this.state.isShowTask}
          cancelText="取消"
          okText="保存"
          onOk={this.taskOnOk}
          onCancel={() => {
            this.setState({
              isShowTask: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              ref={this.taskForm}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 19 }}
              autoComplete="off"
            >
              <Item
                label="作业名称"
                name="taskName"
                rules={[
                  { required: true, message: '请输入作业名称' },
                ]}
              >
                <Input placeholder="请输入作业名称" />
              </Item>
              <Item
                label="父级目录"
                name="pid"
              >
                <TreeSelect
                  allowClear
                  showSearch
                  getPopupContainer={(triggerNode) => triggerNode.parentNode}
                  // dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                  treeData={treeOption}
                  placeholder="请选择父级目录"
                  treeDefaultExpandAll
                  filterTreeNode={(input, treeNode) => treeNode.name.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                  fieldNames={{
                    label: 'name', value: 'id', children: 'childs',
                  }}
                />
              </Item>
              <Item
                label="描述"
                name="remark"
              >
                <TextArea
                  placeholder="请输入描述"
                  rows={3}
                />
              </Item>
            </Form>
          </div>
        </Modal>
        <Modal
          title="移动"
          confirmLoading={this.state.confirmLoading}
          visible={this.state.moveShow}
          cancelText="取消"
          okText="确认"
          // onOk={() => {
          //   this.dataDevDirChange()
          // }}
          onCancel={() => {
            this.setState({
              moveShow: false,
            })
          }}
        >
          <div className={styles.file_box}>
            {/* <MoveForm
              task={this.state.item}
              ref={(div) => (this.moveForm = div)}
            /> */}
          </div>
        </Modal>
      </div>
    )
  }
}

export default connect(({
  global,
  scriptDev
}) => ({ themeValue: global.themeValue, ...scriptDev }))(withRouter(DataDevTree))
